/*


 */

package jas.rpc.http;

import jas.rpc.*;
import jas.rpc.server.*;
import jas.http.request.HttpRequest;
import jas.http.response.HttpResponse;
import jas.http.response.ResponseCode;
import jas.http.response.StringResponseBody;

/**
 *
 *
 */
public class RpcHttpServerFormatterImpl implements RpcHttpServerFormatter {
    
    private ObjectServerSerializer serializer;
    private ObjectIdBank ids;
    
    public RpcHttpServerFormatterImpl(ObjectServerSerializer serializer, ObjectIdBank ids) {
        this.ids = ids;
        this.serializer = serializer;
    }
    
    public RpcRequest parseRequest(HttpRequest request) throws IllegalArgumentException {
        String[] parts = request.getPath().split("\\|"); // TODO: Check length of parts[]
        
        if (parts.length < 2)
            throw new IllegalArgumentException("Incomplete URI: " + request.getPath());
        
        String objectId = parts[0];
        String methodName = parts[1];
        String[] parameters = new String[0];
        String[] classes = new String[0];
        if (parts.length >= 4) {
            parameters = parts[2].split("&");
            classes = parts[3].split("&");
        }
        
        if (parameters.length != classes.length) {
            throw new IllegalArgumentException("Not a valid RPC request. Number of parameters and parameter types are not the same.");
        }
        
        try {
            Object[] paramObjects = new Object[parameters.length];
            for (int i=0; i<parameters.length; i++) {
                paramObjects[i] = serializer.deserializeObject(parameters[i], ids);
            }
            
            Class[] classObjects = new Class[classes.length];
            for (int i=0; i<classes.length; i++) {
                classObjects[i] = Class.forName(classes[i]);
            }
            
            return new RpcRequest(ids.getObjectWithId(objectId), methodName, paramObjects, classObjects);  
            
        } catch (ClassNotFoundException ex) {
            throw new IllegalArgumentException("Invalid RPC request: Class not found: " + ex.getMessage());
        }
    }

    public HttpResponse writeResponse(Object returnValue) {
        HttpResponse response = new HttpResponse();
        response.setCode(ResponseCode.OK);
        
        String encoded = serializer.serializeObject(returnValue, ids);
        response.setBody(new StringResponseBody(encoded));
        
        return response;
    }
    
    public HttpResponse writeException(Exception e) {
        HttpResponse response = new HttpResponse();
        String body = "";
        response.setCode(ResponseCode.INTERNAL_SERVER_ERROR);
        body = e.getClass().getName() + " " + e.getMessage();
        response.setBody(new StringResponseBody(body));
        return response;
    }

}
